<?php

class KoechLabelOverlappingValidator extends sfValidatorSchema
{
  public function __construct($options = array(), $messages = array())
  {
    parent::__construct(null, $options, $messages);
  }
  
  protected function configure($options = array(), $messages = array())
  {
    $overlapping = 'Overlapping with koech label %name%.';
    $this->addOption('throw_global_error', true);
    $this->addMessage('overlapping', $overlapping);
  }
  
  protected function doClean($values)
  {
    if (!is_array($values))
    {
      throw new InvalidArgumentException('You must pass an array parameter to the clean() method (this validator can only be used as a post validator).');
    }
    
    // not to validate when there is no store-product or discount type chosen
    if (!$values['date_from'] || !$values['date_to'])
    {
      return $values;
    }
    
    $q = kcDoctrineQuery::create()
         ->from('KoechLabel k');   //$c = new Criteria();
    if ($values['id'])
    {
      $q->where('k.id <> ?', $values['id']);    //$c->add(KoechLabelPeer::ID, $values['id'], Criteria::NOT_EQUAL);
    }
    $koechLabels = $q->execute(); // KoechLabelPeer::doSelect($c);
    
    // not to validate if not general discount and there is no bottom qty or top qty, or if bottom > top
    $conditions = !$values['date_from'] || !$values['date_to'] || (strtotime($values['date_from']) > strtotime($values['date_to']));
    if ($conditions)
    {
      return $values;
    }
    
    $errors = array();
    foreach ($koechLabels as $koechLabel)
    {
      $error = null;
      if ($this->isOverlapWith($values['date_from'], $values['date_to'], $koechLabel->getDateFrom(), $koechLabel->getDateTo()))
      {
        $error = new sfValidatorError($this, 'overlapping', array('name' => $koechLabel->getName()));
      }
      
      if ($error)
      {
        $errors[] = $error;
      }
    }
    
    if ($errors)
    {
      throw new sfValidatorErrorSchema($this, $errors);
    }
    if ($this->getOption('throw_global_error'))
    {
      throw $error;
    }
    
    return $values;
  }
  protected function isOverlapWith($date_from, $date_to, $o_date_from, $o_date_to)
  {
    /**
     * to avoid overlapping for bottom and top quantities,
     * all the other offer's bottom and top quantities must be or less or greater than both.
     */ 
    $date_from   = strtotime($date_from);
    $date_to     = strtotime($date_to);
    $o_date_from = strtotime($o_date_from);
    $o_date_to   = strtotime($o_date_to);
    
    $isnt_overlap = ($date_from < $o_date_from && $date_to < $o_date_from) || ($date_from > $o_date_to && $date_to > $o_date_to);

    return !$isnt_overlap;
  }
}
